/*******************************************************************************
 * Package: com.hngtrust.iir.bond.service.impl
 * Type:    BondBusServiceImpl
 * Date:    2021/12/14 11:11 上午
 *
 * Copyright (c) 2021 -------- -------- CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.bond.service.impl;

import com.hngtrust.framework.bind.ResponseInfo;
import com.hngtrust.framework.page.PageResult;
import com.hngtrust.framework.page.service.PageService;
import com.hngtrust.iir.base.entity.Dict;
import com.hngtrust.iir.base.service.DictService;
import com.hngtrust.iir.base.service.IndustryService;
import com.hngtrust.iir.bond.dto.*;
import com.hngtrust.iir.bond.entity.BondBaseInfo;
import com.hngtrust.iir.bond.entity.PledgeCode;
import com.hngtrust.iir.bond.service.*;
import com.hngtrust.iir.company.service.CompanyService;
import com.hngtrust.iir.dto.ReqDTO;
import com.hngtrust.iir.util.ListUtil;
import com.tiger.excel.ExcelUtils;
import com.tiger.web.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 债券信息
 *
 * @author Chaidd
 * @date 2021/12/14 11:11 上午
 */
@Service
@Slf4j
public class BondBusServiceImpl implements BondBusService {

    /**
     * 分页服务
     */
    @Autowired
    private PageService pageService;

    @Autowired
    private BondBaseInfoService bondBaseInfoService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private IndustryService industryService;

    @Autowired
    private BondRatingService bondRatingService;

    @Autowired
    private PledgeCodeService pledgeCodeService;

    @Autowired
    private BondIssuerRatingService bondIssuerRatingService;

    @Autowired
    private BondAgencyService bondAgencyService;

    @Autowired
    private DictService dictService;

    @Autowired
    private FileService fileService;

    @Value("${bondDownTmp.url}")
    private String bondDownURL;

    @Autowired
    @Qualifier("localFileService")
    private FileService localFileService;


    /**
     * 债券信息查询
     * @param bondReq
     * @return
     */
    @Override
    public ResponseInfo<PageResult<BondRespVO>> queryBond(ReqDTO<BondReq> bondReq) {
        BondReqDTO bondReqDTO = new BondReqDTO();
        if(bondReq.getContent() != null){
            BeanUtils.copyProperties(bondReq.getContent(),bondReqDTO);
        }
        PageResult<BondBaseInfo> bondBaseInfoPageResult = pageService.page(bondReq.getPageParam(),() -> bondBaseInfoService.queryListByReq(bondReqDTO));
        PageResult<BondRespVO> bondRespVOPageResult = new PageResult<>();
        List<BondRespVO> bondRespVOList = new ArrayList<>();
        for(BondBaseInfo bondBaseInfo : bondBaseInfoPageResult.getRows()){
            getBondRespVOList(bondRespVOList, bondBaseInfo);
        }
        bondRespVOPageResult.setRows(bondRespVOList);
        bondRespVOPageResult.setPage(bondBaseInfoPageResult.getPage());
        return new ResponseInfo(bondRespVOPageResult);
    }

    /**
     * 债券类型查询
     * @return
     */
    @Override
    public ResponseInfo<List<BondTypeRespVO>> queryBondType() {
        List<BondBaseInfo> bondBaseInfoList = bondBaseInfoService.queryBondType();
        List<BondTypeRespVO> bondTypeRespVOList = new ArrayList<>();
        ListUtil<BondTypeRespVO> listUtil = BeanUtils.instantiateClass(ListUtil.class);
        listUtil.copyList(bondBaseInfoList,bondTypeRespVOList,BondTypeRespVO.class);
        return new ResponseInfo<>(bondTypeRespVOList);
    }

    @Override
    public void templateDownload(HttpServletResponse response) {
        // minio上下载Excel模板文件
        fileService.download(bondDownURL, response);
    }

    @Override
    public ResponseInfo<BondTmpRespVO> queryBatchBond(MultipartFile file) throws IOException {
        final File tempFile = File.createTempFile("temp", ".xls");
        FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);
        List<BondTmpDTO> bondTmpDTOList = null;
        bondTmpDTOList = ExcelUtils.importFromExcel(tempFile, BondTmpDTO.class);
        if (bondTmpDTOList.size()>500) {
            bondTmpDTOList = bondTmpDTOList.subList(0, 500);
        }
        BondTmpRespVO bondTmpRespVO = new BondTmpRespVO();
        List<String> strings = new ArrayList<>();
        for(BondTmpDTO bondTmpDTO : bondTmpDTOList){
            if(bondTmpDTO.getCode() != null){
                strings.add(bondTmpDTO.getCode());
            }
        }
        bondTmpRespVO.setBatchCodes(strings);
        return new ResponseInfo<>(bondTmpRespVO);
    }

    @Override
    public void dataExport(ReqDTO<BondReq> bondReq, HttpServletResponse response) throws IOException {
        BondReqDTO bondReqDTO = new BondReqDTO();
        if(bondReq.getContent() != null){
            BeanUtils.copyProperties(bondReq.getContent(),bondReqDTO);
        }
        PageResult<BondBaseInfo> bondBaseInfoPageResult = pageService.page(bondReq.getPageParam(),() -> bondBaseInfoService.queryListByReq(bondReqDTO));
//        List<BondBaseInfo> bondBaseInfoList = bondBaseInfoService.queryListByReq(bondReqDTO);
        List<BondRespVO> bondRespVOList = new ArrayList<>();
        List<BondExpRespVO> bondExpRespVOS = new ArrayList<>();
        for(BondBaseInfo bondBaseInfo : bondBaseInfoPageResult.getRows()){
            getBondRespVOList(bondRespVOList, bondBaseInfo);
        }
        ListUtil<BondExpRespVO> listUtil = BeanUtils.instantiateClass(ListUtil.class);
        listUtil.copyList(bondRespVOList,bondExpRespVOS,BondExpRespVO.class);
        String directory = System.getProperty("java.io.tmpdir");
        File file = new File(directory,"bondDown.xls");
        //导出数据到本机默认路径
        ExcelUtils.export2Excel(bondExpRespVOS,file);
        //下载文件，下载成功后删除文件
        localFileService.download(file.getAbsolutePath(), response);
        try {
            if(!file.delete()){
                log.error("删除本地临时文件错误：{}" , directory+"/"+file.getName());
            }
        }
        catch (Exception e) {
            log.error("删除本地临时文件错误：{}" , directory+"/"+file.getName());
        }
    }

    @Override
    public ResponseInfo<PageResult<BondRatingDetailRespVO>> queryBondRating(ReqDTO<BondDetailReq> bondDetailReq) {
        BondDetailReqDTO bondDetailReqDTO = new BondDetailReqDTO();
        if(bondDetailReq.getContent() != null){
            BeanUtils.copyProperties(bondDetailReq.getContent(),bondDetailReqDTO);
        }
        PageResult<BondRatingDetailRespVO> bondBaseInfoPageResult = new PageResult<>();
        PageResult<BondRatingDetailRespDTO> bondRatingDetailRespDTOPageResult = pageService.page(bondDetailReq.getPageParam(),() -> bondIssuerRatingService.queryListByReq(bondDetailReqDTO));
        bondBaseInfoPageResult.setPage(bondRatingDetailRespDTOPageResult.getPage());
        List<BondRatingDetailRespVO> bondRatingDetailRespVOList = new ArrayList<>();
        List<BondRatingDetailRespDTO> bondRatingDetailRespDTOList = bondRatingDetailRespDTOPageResult.getRows();
        ListUtil<BondRatingDetailRespVO> listUtil = BeanUtils.instantiateClass(ListUtil.class);
        listUtil.copyList(bondRatingDetailRespDTOList,bondRatingDetailRespVOList,BondRatingDetailRespVO.class);
        bondBaseInfoPageResult.setRows(bondRatingDetailRespVOList);
        return new ResponseInfo<>(bondBaseInfoPageResult);
    }

    @Override
    public ResponseInfo<BondDetailRespVO> queryBondDetail(ReqDTO<BondDetailReq> bondDetailReq) {
        BondDetailRespVO bondDetailRespVO = new BondDetailRespVO();
        BondBaseInfo bondBaseInfo = bondBaseInfoService.queryById(bondDetailReq.getContent().getId());
        BeanUtils.copyProperties(bondBaseInfo,bondDetailRespVO);
        bondDetailRespVO.setCompAddress(companyService.queryById(bondBaseInfo.getCompId()).getAddress());
        Map<String, Dict> compPropertyCode = dictService.queryDict("COMP_PROPERTY");
        Map<String, Dict> bondPropertyCode = dictService.queryDict("BOND_TYPE");
        bondDetailRespVO.setBondType(bondBaseInfo.getBondType() == null ? "" : dictService.queryDictByCode(bondPropertyCode,bondBaseInfo.getBondType()).getBusiName());
        if (companyService.queryById(bondBaseInfo.getCompId()).getCompProperty() != null) {
            bondDetailRespVO.setCompProperty(dictService.queryDictByCode(compPropertyCode,companyService.queryById(bondBaseInfo.getCompId()).getCompProperty().toString()).getBusiName());
        }
        List<BondAgencyDTO> agencyBusList = bondAgencyService.queryListByAgency(bondDetailReq.getContent().getCode(),"10");
        List<BondAgencyDTO> agencyOrgList = bondAgencyService.queryListByAgency(bondDetailReq.getContent().getCode(),"21");
        bondDetailRespVO.setAgencyOrg(agencyOrgList);
        bondDetailRespVO.setAgencyBus(agencyBusList);
        PledgeCode pledgeCode = new PledgeCode();
        pledgeCode.setBondId(bondDetailReq.getContent().getId());
        List<PledgeCode> agencyPledgeList = pledgeCodeService.queryList(pledgeCode);

        StringBuilder stringBuilderPledge = new StringBuilder();
        if (agencyPledgeList.size() > 0){
            for (PledgeCode pledgeCode1 : agencyPledgeList) {
                stringBuilderPledge.append(pledgeCode1.getPledgeCode());
                stringBuilderPledge.append("，");
            }
        }
        String inSqlPledge = stringBuilderPledge.toString();
        if (StringUtils.isNotEmpty(inSqlPledge)){
            String subPledge = inSqlPledge.substring(0, inSqlPledge.length()-1);
            bondDetailRespVO.setPledgeCode(subPledge);
        }else {
            bondDetailRespVO.setPledgeCode("");
        }

        //剩余年限
        Date date = new Date();
        log.info("****************到期日***************"+bondDetailRespVO.getMaturitydate().getTime());
        log.info("****************当前日***************"+date.getTime());
        BigDecimal shengDate = BigDecimal.valueOf((bondDetailRespVO.getMaturitydate().getTime() - date.getTime())/(1000*3600*24));
        BigDecimal yearDate = BigDecimal.valueOf(365);
        BigDecimal shengDateYear = shengDate.divide(yearDate,4,BigDecimal.ROUND_HALF_UP);
        log.info("****************年限***************"+shengDateYear);
        bondDetailRespVO.setShengDate(shengDateYear);
        if(bondBaseInfo.getInteresttype().compareTo(BigDecimal.valueOf(501001000)) == 0){
            bondDetailRespVO.setInteresttype("浮动利率");
        }else if(bondBaseInfo.getInteresttype().compareTo(BigDecimal.valueOf(501002000)) == 0){
            bondDetailRespVO.setInteresttype("固定利率");
        }else if(bondBaseInfo.getInteresttype().compareTo(BigDecimal.valueOf(501003000)) == 0){
            bondDetailRespVO.setInteresttype("累进利率");
        }
        if(bondBaseInfo.getCoupon().compareTo(BigDecimal.valueOf(505001000)) == 0){
            bondDetailRespVO.setCoupon("附息");
        }else if(bondBaseInfo.getCoupon().compareTo(BigDecimal.valueOf(505002000)) == 0){
            bondDetailRespVO.setCoupon("零息:指存续期内不付息,到期一次还本付息的债券");
        }else if(bondBaseInfo.getCoupon().compareTo(BigDecimal.valueOf(505003000)) == 0){
            bondDetailRespVO.setCoupon("贴现");
        }
        if(bondBaseInfo.getUnderwritingcode().compareTo(BigDecimal.valueOf(438001000)) == 0){
            bondDetailRespVO.setUnderwritingcode("代销");
        }else if(bondBaseInfo.getUnderwritingcode().compareTo(BigDecimal.valueOf(438002000)) == 0){
            bondDetailRespVO.setUnderwritingcode("全额包销");
        }else if(bondBaseInfo.getUnderwritingcode().compareTo(BigDecimal.valueOf(438003000)) == 0){
            bondDetailRespVO.setUnderwritingcode("全额包销,代销");
        }else if(bondBaseInfo.getUnderwritingcode().compareTo(BigDecimal.valueOf(438004000)) == 0){
            bondDetailRespVO.setUnderwritingcode("余额包销");
        }else if(bondBaseInfo.getUnderwritingcode().compareTo(BigDecimal.valueOf(438005000)) == 0){
            bondDetailRespVO.setUnderwritingcode("余额包销,代销");
        }else if(bondBaseInfo.getUnderwritingcode().compareTo(BigDecimal.valueOf(438006000)) == 0){
            bondDetailRespVO.setUnderwritingcode("限额包销");
        }

        bondDetailRespVO.setSubordinateornot(bondBaseInfo.getSubordinateornot() == 1 ? "是" : "否");
        bondDetailRespVO.setIscallable(bondBaseInfo.getIscallable() == 1 ? "是" : "否");
        bondDetailRespVO.setIspayadvanced(bondBaseInfo.getIspayadvanced() == 1 ? "是" : "否");
        bondDetailRespVO.setIschooseright(bondBaseInfo.getIschooseright() == 1 ? "是" : "否");
        bondDetailRespVO.setIsinright(bondBaseInfo.getIsinright() == 1 ? "是" : "否");
        bondDetailRespVO.setIscorporateBond(bondBaseInfo.getIscorporateBond() == 1 ? "是" : "否");
        bondDetailRespVO.setIsactDays(bondBaseInfo.getIsactDays() == 1 ? "是" : "否");
        bondDetailRespVO.setIsincbonds(bondBaseInfo.getIsincbonds() == 1 ? "是" : "否");


        return new ResponseInfo<>(bondDetailRespVO);
    }


    private void getBondRespVOList(List<BondRespVO> bondRespVOList, BondBaseInfo bondBaseInfo) {
        BondRespVO bondRespVO = new BondRespVO();
        BeanUtils.copyProperties(bondBaseInfo,bondRespVO);
        if(bondBaseInfo.getCompId() != null){
            bondRespVO.setIssuerAddress(companyService.queryById(bondBaseInfo.getCompId()).getAddress());
            Long industryId = companyService.queryById(bondBaseInfo.getCompId()).getIndustry();
            bondRespVO.setIndustryName(industryId == null ? null : industryService.queryIndustry(industryId).getName());
        }

        if(bondBaseInfo.getInteresttype() != null){
            if(bondBaseInfo.getInteresttype().compareTo(BigDecimal.valueOf(501001000)) == 0){
                bondRespVO.setInteresttype("浮动利率");
            }else if(bondBaseInfo.getInteresttype().compareTo(BigDecimal.valueOf(501002000)) == 0){
                bondRespVO.setInteresttype("固定利率");
            }else if(bondBaseInfo.getInteresttype().compareTo(BigDecimal.valueOf(501003000)) == 0){
                bondRespVO.setInteresttype("累进利率");
            }
        }
        if(bondBaseInfo.getExchmarket() != null){
            if(bondBaseInfo.getExchmarket().equals("SSE")){
                bondRespVO.setExchmarket("上交所");
            }else if(bondBaseInfo.getExchmarket().equals("SZSE")){
                bondRespVO.setExchmarket("深交所");
            }else if(bondBaseInfo.getExchmarket().equals("NIB")){
                bondRespVO.setExchmarket("银行间债券");
            }else if(bondBaseInfo.getExchmarket().equals("NBC")){
                bondRespVO.setExchmarket("银行柜台债券");
            }
        }

        if(bondBaseInfo.getIssuetype() != null){
            if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439002000)) == 0){
                bondRespVO.setIssuetype("包销团包销");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439004000)) == 0){
                bondRespVO.setIssuetype("比例配售");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439006000)) == 0){
                bondRespVO.setIssuetype("定向");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439049000)) == 0){
                bondRespVO.setIssuetype("优先配售和上网定价");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439048000)) == 0){
                bondRespVO.setIssuetype("优先配售，网下配售");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439047000)) == 0){
                bondRespVO.setIssuetype("优先配售，网上定价和网下配售");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439045000)) == 0){
                bondRespVO.setIssuetype("优先配售，定向配售和网上定价");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439037000)) == 0){
                bondRespVO.setIssuetype("网下发行");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439033000)) == 0){
                bondRespVO.setIssuetype("网上发行");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439032000)) == 0){
                bondRespVO.setIssuetype("贴现发行");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439010000)) == 0){
                bondRespVO.setIssuetype("公开发行");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439030000)) == 0){
                bondRespVO.setIssuetype("私募");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439025000)) == 0){
                bondRespVO.setIssuetype("上网定价和网下配售");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439022000)) == 0){
                bondRespVO.setIssuetype("上网定价");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439019000)) == 0){
                bondRespVO.setIssuetype("平价发行");
            }else if(bondBaseInfo.getIssuetype().compareTo(BigDecimal.valueOf(439012000)) == 0){
                bondRespVO.setIssuetype("公募");
            }
        }


        bondRespVOList.add(bondRespVO);
    }
}
